perm filename NMIX.FAI[IRC,LCS] blob sn#230596 filedate 1977-03-30 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00011 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002		TITLE MIXER
C00004 00003		CLRBFI
C00007 00004	DLAY:	ADD DUR,BC1		ADD 1st BUFFER TO DURAITOM
C00010 00005	SPLICE:	SETOM SFLG#		SET SPLICE FLAG
C00012 00006			1st FILE INPUT SUB
C00015 00007			2nd FILE INPUT SUB
C00018 00008	GDLAY:	CLRBFI
C00020 00009			DEFAULT FILE NAMES
C00022 00010	GETNAM:	MOVEI A,
C00023 00011			FLOATING POINT INPUT
C00025 ENDMK
C⊗;
	TITLE MIXER
	A←1 ↔ B←2 ↔ C←3	;POINTERS TO INBUF #1,#2, AND OUTBUF
	D←4 ↔ E←5
	DUR←6 ↔ MAX←7	;TOTAL DURATION, MAXIMUM AMP
	R1←10 ↔ R2←11	;RATIO #1, RATIO #2 , DEFAULT = .5
	R3←12
	BC1←13 ↔ BC2←14 ↔ BC3←15 ;SAMPLE COUNTS, 1st,2nd, 3rd = out buf
	P←17 ↔ NBUFS←←4	;p = PDL,  NUMBER OF BUFFERS (MAYBE SHOULD BE MORE)

MIXER:	MOVE P,[IOWD 20,PDL]	;SETUP PUSH DOWN LIST
	CLRBFI
	OUTSTR [ASCIZ/
	TYPE FIRST NAME : /]
	SETZ BC1,		;SET TO 0 FOR DEFAULT FILE NAME
	PUSHJ P,GNAME
	OPEN 11,[14↔'DSK   '↔BUF1]
	JRST 4,.
	INBUF 11,NBUFS		;SETUP 1st INPUT BUFFER RING
	LOOKUP 11,FILNAM
	JRST MIXER
	AOJ BC1,		;SET TO 1 FOR SECOND DEFAULT FILE NAME

SECOND:	CLRBFI
	OUTSTR [ASCIZ/	TYPE SECOND NAME : /]
	PUSHJ P,GNAME
	OPEN 2,[14↔'DSK   '↔BUF2]
	JRST 4,.
	INBUF 2,NBUFS		;SETUP 2nd INPUT BUFFER RING
	LOOKUP 2,FILNAM
	JRST SECOND
	AOJ BC1,		;SET TO 2 FOR OUTPUT DEFAULT FILE NAME

	CLRBFI
	OUTSTR [ASCIZ/	NUMBER OF CHANNELS (DEFAULT=1) -- /]
	INCHWL A
	PUSHJ P,INNUM
	SKIPLE
	CAILE 4
	HRRZI 1
	HRRZM NCHNLS#
	CLRBFI
	OUTSTR [ASCIZ/	SRATE (DEFAULT=12800) -- /]
	INCHWL A
	PUSHJ P,INNUM
	SKIPN
	HRRZI =12800		;SRATE DEFAULT
	FLTR 0,0
	MOVEM FSRATE#		;FLOATING SRATE
	PUSHJ P,GDLAY
	MOVEM SNUM2#		;SECOND FILE DELAY

GBITS:	CLRBFI
	OUTSTR [ASCIZ/	NUMBER OF BITS PER SAMPLE? (DEFAULT=12) -- /]
	INCHWL A
	PUSHJ P,INNUM
	CAIE =18
	JRST CK12
	MOVE [-1,,0]		;MUNG CODE FOR 18 BITS
	MOVEM NEG
	HRRZI 400000
	HRRM N1
	HRRM N2
	HRRM N3
	HRRZI -11
	HRRM A1
	HRRM A2
	HRRZI 2			;SETUP 18 BIT FLAG
	JRST GOTB

CK12:	CAIE =12
	JUMPN GBITS
	MOVE [777777774000]	;MUNG CODE FOR 12 BITS
	MOVEM NEG
	HRRZI 774000
	HRRM N1
	HRRM N2
	HRRM N3
	HRRZI -14
	HRRM A1
	HRRM A2
	SETZ			;SETUP 12 BIT FLAG
GOTB:	HRRZM NBITS#		;NBITS = 0 IF 12 BITS, =2 IF 18 BITS
	
GRAT:	CLRBFI
	OUTSTR [ASCIZ/
  DEFAULT AMPL. FACTOR RATIO = .5:.5
  TYPE SPLICE OR RATIO (S OR <R1>:<R2>) -- /]
	INCHWL A
	CAIE A,"s"
	CAIN A,"S"
	JRST SPLICE
	SETZM SFLG#		;SPLICE FLAG
	PUSHJ P,GETNUM
	SKIPG R1,
	MOVE R1,[DOT5:	=0.5]
	SKIPN NBITS
	FMPR R1,[=4096.]	;SHIFT TO MIDDLE OF WORD
	SKIPE NBITS
	FMPR R1,[=512.]
	KIFIX R1,R1
	INCHRS A
	JRST .+3		;NO DOT
	PUSHJ P,GETNUM
	SKIPG R2,
	MOVE R2,DOT5
	SKIPN NBITS
	FMPR R2,[=4096.]	;SHIFT TO MIDDLE OF WORD
	SKIPE NBITS
	FMPR R2,[=512.]
	KIFIX R2,R2
	PUSHJ P,ONAME		;GET OUTPUT FILE NAME
	AOJ BC2,		;??
	SETZ MAX,		;START AT 0 MAX AMP
	SETOM DFLG#		;SET DELAY FLAG
DLAY:	ADD DUR,BC1		;ADD 1st BUFFER TO DURAITOM
	CAML DUR,SNUM2		;CHECK IF PAST 2nd START TIME
	JRST FIND
	PUSHJ P,MOV		;COPY 1st FILE TO OUTPUT
	PUSHJ P,IN1		;GET MORE INPUT
	JRST DLAY

;			COPIER SUB
MOV:	ILDB D,A		;GET INPUT SAMPLE
N1:	TRNE D,774000		;CHECK IF NEGATIVE
	TDO D,[NEG: 777777774000]	;MAKE NEGATIVE
	IMUL D,R1		;MULTIPLY BY FIRST RATIO
A1:	ASH D,-14		;SHIFT END OF WORD (NO FRACTION)
	CAMLE D,MAX		;CHECK IF > MAX AMP
	MOVE MAX,D		;NEW MAX
	IDPB D,C		;STORE IN OUT BUF
	SOJLE BC3,MOVO		;CHECK FOR FULL OUT BUF
	SOJG BC1,MOV		;MORE COPY?
	POPJ P,

MOVO:	PUSHJ P,OBUF		;GET NEW OUT BUF
	SOJG BC1,MOV		;MORE COPY?
	POPJ P,

;			END OF FIRST DELAY
FIND:	SUB DUR,SNUM2		;GET COUNT OF FIRST MIX BUFFER
	SOJ BC2,		;??

	SUB BC1,DUR		;GET COPY COUNT
	SKIPLE BC1
	PUSHJ P,MOV		;COPY END OF DELAY
SETFLG:	SETZM DFLG		;NO MORE DELAY
	SKIPG BC1,DUR		;GET REST OF 1st BUF COUNT
	PUSHJ P,IN1		;GET NEW INBUF IF EMPTY
	MOVE DUR,SNUM2		;DURATION ← DELAY TIME
	ADD DUR,BC2		;DUR ← DUR + OUT BUF COUNT
	
MIX:	ILDB D,A		;GET 1st SAMPLE
N2:	TRNE D,774000		;FIX FOR NEGATIVE
	TDO D,NEG
	ILDB E,B		;GET 2nd SAMPLE
N3:	TRNE E,774000		;FIX FOR NEGATIVE
	TDO E,NEG
	IMUL D,R1		;* 1st RATIO
	IMUL E,R2		;* 2nd RATIO
	ADD D,E			;MIX TWO SAMPLES
A2:	ASH D,-14		;GET RID OF FRACTION
	CAMLE D,MAX
	MOVE MAX,D		;UPDATE MAX AMP
	IDPB D,C		;STORE IN OUT BUF
	SOJLE BC3,MIXO		;CHECK FOR FULL OUT BUF
CKIN:	SOJLE BC1,MIXI		;CHECK FOR 1st IN BUF FULL
	SOJG BC2,MIX		;CHECK FOR 2nd IN BUF FULL
	PUSHJ P,IN2		;GET NEW IN BUF #2
	ADD DUR,BC2		;UPDATE DURATION
	JRST MIX

MIXO:	PUSHJ P,OBUF		;GET NEW OUT BUF
	JRST CKIN
MIXI:	PUSHJ P,IN1		;GET NEW IN BUF #1
	JRST CKIN+1
SPLICE:	SETOM SFLG#		;SET SPLICE FLAG
	PUSHJ P,ONAME		;GET OUTPUT FILE NAME
SLOOP:	ADD DUR,BC3		;ADD OUT COUNT TO DURATION
	CAML DUR,SNUM2		;CHECK IF PAST SECOND START TIME
	JRST NXPART
	PUSHJ P,SPLOP		;COPY IT
	PUSHJ P,OBUF		;OUTPUT IT
	PUSHJ P,IN1		;GET MORE INPUT
	JRST SLOOP

;		SPLICE COPIER SUB
SPLOP:	ILDB D,A		;GET SAMPLE FROM IN BUF
	IDPB D,C		;STORE SAMPLE IN OUT BUF
	SOJG BC3,SPLOP		;CHECK IF OUT BUF FULL
	POPJ P,

;		SECOND FILE START
NXPART:	SUB DUR,SNUM2
	SUB BC3,DUR		;GET NUMBER OF SAMPLES LEFT IN 1st FILE
	SKIPLE BC1,BC3		;SET UP 1st BYTE COUNT WITH NUMBER LEFT IN OUTBUF
	PUSHJ P,SPLOP		;COPY LAST SAMPLES OF 1st FILE IF ANY

FINSH:	MOVE A,B		;SETUP 1st POINTER TO POINT TO 2nd INBUF
	SKIPLE BC3,DUR		;OUTBUF COUNT ← NUMBER LEFT IN OUTBUF
	PUSHJ P,SPLOP		;FILL REST OF OUTBUF WITH 2nd INBUF, IF ANY
	PUSHJ P,OBUF 		;OUTPUT IT
	EXCH DUR,SNUM2		;DURATION ← DELAY TIME, SAVE COUNT BETWEEN IN & OUT

FIL2:	ADD DUR,BC2		;ADD 2nd INBUF COUNT TO DURATION
	SKIPLE BC3,BC1		;OUTBUF COUNT ← NUMBER LEFT IN OUTBUF
	PUSHJ P,SPLOP		;COPY IT
	PUSHJ P,IN2		;GET MORE OF 2nd FILE
	MOVE A,B		;POINT TO 2nd INBUF
	SKIPLE BC3,SNUM2	;SETUP IN TO OUT COUNT
	PUSHJ P,SPLOP		;COPY IT
	PUSHJ P,OBUF		;OUTPUT IT
	JRST FIL2
;		1st FILE INPUT SUB
IN1:	IN 11,
	CAIA
	JRST CKEOF
	SKIPN BC1,NBITS
	HRRZI BC1,3
	IMUL BC1,BUF1+2		;MULTIPLY WORD COUNT BY NUM OF SAMPLES IN A WORD
	HRRZ A,BUF1+1		;POINT TO 1st INBUF
	HRLI A,1400		;NUMBER OF BITS IN SAMPLE
	SKIPE NBITS
	HRLI A,2200
	POPJ P,

CKEOF:	STATO 11,20000		;CHECK FOR ERROR
	JRST 4,.
	SETOM EOF1		;SET END OF FILE #1
	SKIPGE EOF2		;CHECK IF SECOND FILE DONE
	JRST DONE
	SKIPL SFLG
	SKIPGE DFLG
	JRST BREAK		;FILL WITH ZEROS IF SPLICE OR DELAY
PART2:	MOVE R1,R2		;RATIO #1 ← RATIO #2
	SOJLE BC2,GMOR		;CHECK FOR MORE 2nd INPUT
	MOVE BC1,BC2		;SAMPLE COUNT #1 ← SAMPLE COUNT #2
	MOVE A,B		;POINT TO INBUF #2
	PUSHJ P,MOV		;COPY IT
GMOR:	PUSHJ P,IN2		;GET MORE INPUT
	ADD DUR,BC2		;UPDATE DURATION
	JRST PART2+2

BREAK:	SUB DUR,SNUM2		;DUR ← NEGATIVE NUMBER OF SAMPLES TO ZERO
	SKIPGE SFLG
	JRST ZSPL		;JUMP IF SPLICE
	SETZ D,
ZRIT:	IDPB D,C		;ZERO SAMPLE IN OUTBUF
	SOJLE BC3,ZOB		;CHECK IF OUTBUF FULL
	AOJL DUR,ZRIT		;ZERO REST OF DELAY BETWEEN FILES
	MOVE DUR,SNUM2		;DURATION ← DELAY TIME
	JRST PART2

ZOB:	PUSHJ P,OBUF		;GET NEW OUTBUF
	JRST ZRIT+2

ZSLOP:	ADD DUR,BC3
	JUMPG DUR,ZEND		;ALMOST DONE IF OUTBUF COUNT + DURATION > DELAY
	HRLI C,-200
	SETZM 1(C)		;ZERO OUTBUF
	AOBJN C,.-1
	PUSHJ P,OBUF		;OUTPUT IT
ZSPL:	JUMPL DUR,ZSLOP		;JUMP IF MORE THAN ONE OUTBUF
	HRRZI BC1,600		;??
	SKIPE NBITS
	HRRZI BC1,400
	JRST EQEND

ZEND:	MOVE DUR
	SUB BC3
	MOVN BC1,		;BYTE COUNT #1 ← NUM OF SAMPLES LEFT IN OUTBUF
	SETZ
	IDPB C			;ZERO IT
	AOJL .-1
EQEND:	MOVE A,B		;POINT TO INBUF #2
	POP P,D			;GET RID OF RETURN ADDRESS
	JRST FIL2-1		;??
;		2nd FILE INPUT SUB
IN2:	IN 2,
	CAIA
	JRST CKEOF2
	SKIPN BC2,NBITS
	HRRZI BC2,3
	IMUL BC2,BUF2+2		;MULTIPLY WORD COUNT BY NUM OF SAMPLES IN A WORD
	HRRZ B,BUF2+1		;POINT TO 1st INBUF
	HRLI B,1400		;NUMBER OF BITS IN SAMPLE
	SKIPE NBITS
	HRLI B,2200
	POPJ P,

CKEOF2:	STATO 2,20000		;CHECK FOR ERROR
	JRST 4,.
	SETOM EOF2		;SET END OF FILE FLAG #2
	SKIPL SFLG
	SKIPGE EOF1
	JRST DONE		;DONE IF SPLICE OR FILE #1 DONE
	ADD DUR,BC1		;UPDATE DURATION
	PUSHJ P,MOV		;COPT IT
	PUSHJ P,IN1		;GET MORE INPUT FROM FILE #1
	JRST .-3		;DO INTIL DONE

;		OUTPUT FILE SUB
OBUF:	HRRM C,BUF3+1		;POINT TO LAST OUTBUF WORD
	OUT
	CAIA
	JRST 4,.
	SKIPN BC3,NBITS
	HRRZI BC3,3
	IMUL BC3,BUF3+2		;BC3 ← NUM OF WORDS IN OUTBUF * NUM OF SAMPLES IN A WORD
	HRRZ C,BUF3+1		;POINT TO OUTBUF
	HRLI C,1400		;NUMBER OF BITS IN SAMPLE
	SKIPE NBITS
	HRLI C,2200
	POPJ P,

;		OUTPUT FILE NAME SUB
ONAME:	CLRBFI
	OUTSTR [ASCIZ/
	TYPE OUTPUT NAME (DEFAULT=MIX.SND) -- /]
	PUSHJ P,GNAME
	OPEN [14↔'DSK   '↔BUF3,,0]
	JRST 4,.
	OUTBUF NBUFS		;SETUP OUTPUT BUFFER RING
	ENTER FILNAM
	JRST ONAME
	PUSHJ P,OBUF+1		;+1 → NO OUTPUT YET
	SETZM EOF1#		;INIT END OF FILE #1 FLAG
	SETZM EOF2#		;INIT END OF FILE #2 FLAG
	SETZ DUR,		;DURATION ← 0
	PUSHJ P,IN1		;GET A BUFFER FROM 1st FILE
	PUSHJ P,IN2		;GET A BUFFER FROM 2nd FILE
	POPJ P,
GDLAY:	CLRBFI
	OUTSTR [ASCIZ/	DELAY TIME = /]
	INCHWL A
	PUSHJ P,GETNUM
	HRRZ A,NCHNLS
	FLTR A,A
	FMPR A
	FMPR FSRATE
	KIFIX 0,0
	POPJ P,			;RETURNS WITH NUM OF CHANS * SRATE * DELAY IN AC0

DONE:	PUSHJ P,OBUF		;OUTPUT LAST STUFF
	RELEAS			;FINISH AND RELEASE DISK
	SKIPGE SFLG
	JRST NOMAX		;NO TYPEOUT OF MAX AMP IF SPLICE
	OUTSTR [ASCIZ/
	MAX AMPL = /]
	MOVE MAX
	PUSHJ P,OUTINT		;TYPEOUT MAX AMP
NOMAX:	OUTSTR [ASCIZ/
	NUMBER OF SAMPLES = /]
	MOVE DUR
	PUSHJ P,OUTINT		;TYPEOUT NUMBER OF SAMPLES
	OUTSTR [ASCIZ/
	TOTAL DUR = /]
	IDIV DUR,NCHNLS
	FLTR DUR,DUR
	FDVR DUR,FSRATE
	KIFIX 0,DUR
	PUSHJ P,OUTINT		;TYPEOUT DURATION / NUM OF CHANS / SRATE
	HRRZI "."
	OUTCHR
	MOVE DUR
	KIFIX DUR,DUR
	FLTR DUR,DUR
	FSBR DUR
	FMPR [=10000.]
	KIFIX 0,0
	AOJ
	IDIVI =10
	PUSHJ P,OUTINT		;TYPEOUT REMAINDER
	EXIT
;		DEFAULT FILE NAMES
NAME:	'TEST  '		;1st INPUT	NAME
	'TEST  '		;2nd INPUT
	'MIX   '		;OUTPUT
EXT:	'SND   '		;1st INPUT	EXTENTION
	'SND   '		;2nd INPUT
	'SND   '		;OUTPUT
;		FILE NAME PARSER
GNAME:	SETZM FILEXT+1
	SETZM FILPPN
	MOVE A,EXT(BC1)
	MOVEM A,FILEXT
	PUSHJ P,GETNAM
	SKIPN A
 	MOVE A,NAME(BC1)
GEXT:	MOVEM A,FILNAM
	CAIE C,"."
	JRST NOEXTN
	PUSHJ P,GETNAM
	MOVEM A,FILEXT
NOEXTN:	CAIE C,"["
	JRST FFDX
	PUSHJ P,GETP
	HRLZM A,FILPPN
	PUSHJ P,GETP
	HRRM A,FILPPN
FFDX:	INCHRW C
	CAIE C,12
	JRST FFDX
	POPJ P,
GETNAM:	MOVEI A,
	MOVE B,[440600,,A]
GETNML:	PUSHJ P,RCH
	POPJ P,
	SUBI C,40
	TLNE B,770000
	IDPB C,B
	JRST GETNML

GETP:	MOVEI A,
GETPL:	PUSHJ P,RCH
	POPJ P,
	TRNE A,770000
	JRST GETPL
	LSH A,6
	ADDI A,-40(C)
	JRST GETPL

RCH:	INCHWL C
	CAIN C,42
	JRST RCHQ
	CAIE C,11
	CAIN C," "
	JRST RCH
	CAIE C,"."
	CAIN C,","
	POPJ P,
	CAIE C,"["
	CAIN C,"]"
	POPJ P,
RCHQR:	CAIGE C,40
	POPJ P,
	CAIL C,"a"
	CAILE C,"z"
	CAIA
	SUBI C,40
POPJ1:	AOS (P)
	POPJ P,

RCHQ:	INCHWL C
	JRST RCHQR
;		FLOATING POINT INPUT
GETNUM:	PUSHJ P,INNUM
	FLTR 0,0
	CAIE A,"."
	POPJ P,
	MOVE C,
	INCHRS A
	POPJ P,
	PUSHJ P,INNUM
	JUMPE NODP
	FLTR 0,0
	FMPR TABL(B)
NODP:	FADR C
	POPJ P,

TABL:	=0.1
	=0.01
	=0.001
	=0.0001
	=0.00001

;		INTEGER INPUT
INNUM:	SETZ
	SETO B,
	CAIL A,60
	CAILE A,71
	POPJ P,
	IMULI =10
	ADDI -60(A)
	AOJ B,
	INCHRS A
	POPJ P,
	JRST INNUM+2

;		INTEGER TYPEOUT
OUTINT:	HRRZI B,7
	JUMPE OUTZ
	IDIVI =10
	ADDI A,60
	HRRZM A,BLK(B)
	SOJGE B,OUTINT+1
OCHR:	OUTCHR BLK+1(B)
	CAIGE B,6
	AOJA B,OCHR
	POPJ P,
OUTZ:	CAIL B,7
	HRLZI B,300000
	JRST OCHR

FILNAM:	0
FILEXT:	0
	0
FILPPN:	0
BUF1:	BLOCK 3
BUF2:	BLOCK 3
BUF3:	BLOCK 3
PDL:	BLOCK 44
ACBLK:	BLOCK 20
BLK:	BLOCK 10
	END MIXER